import React, { PropsWithChildren, ReactNode, useMemo, useState, useEffect } from 'react';
import styled, { CSSProperties } from 'styled-components';
import { color, typography } from '../shared/global';
import { darken, rgba, opacify } from 'polished';
import { easing } from '../shared/animation';
import Button from '../button';
import { Icon } from '../icon';
import { PageUl, TableTable, TableHeadSpan } from './styleComponents';

function calculateMove(current: number, state: number[], totalPage: number): number[] | null {
  let mid = Math.floor(state.length / 2);
  let arr;
  let minus = current - state[mid];
  if (minus === 0) {
    arr = null;
  } else if (minus > 0) {
    let tmp = state[state.length - 1];
    if (tmp + minus < totalPage) {
      arr = state.map(v => v + minus);
    } else {
      if (tmp === totalPage) {
        arr = null;
      } else {
        arr = state.map(v => v + totalPage - tmp);
      }
    }
  } else {
    //负数
    if (state[0] + minus > 1) {
      arr = state.map(v => v + minus);
    } else {
      //边缘，看最大能减几
      if (state[0] === 1) {
        arr = null;
      } else {
        arr = state.map(v => v - state[0] + 1);
      }
    }
  }
  return arr;
}

interface PaginationProps {
  /** 每一页显示多少条 */
  pageSize?: number;
  /** 默认显示第几页 */
  defaultCurrent?: number;
  /** 总共条数 */
  total: number;
  /** 分页条目最大显示长度 */
  barMaxSize?: number;
  /** 回调 */
  callback?: (v: number) => void;
  /** 外层style */
  style?: CSSProperties;
  /** 外层类名 */
  classnames?: string;
}

Pagination.defaultProps = {
  pageSize: 10,
  defaultCurrent: 1,
  barMaxSize: 5,
  total: 1000,
};

export function Pagination(props: PaginationProps) {
  const { pageSize, defaultCurrent, barMaxSize, total, callback, style, classnames } = props;
  const [current, setCurrent] = useState(defaultCurrent!);
  const [state, setState] = useState<Array<number>>([]);

  useEffect(() => {
    callback && callback(current);
  }, [callback, current]);

  const totalPage = useMemo(() => {
    let number = Math.ceil(total / pageSize!);
    let statetmp = new Array(number > barMaxSize! ? barMaxSize : number)
      .fill(1)
      .map((x, y) => y + 1);
    setState(statetmp);
    let arr = calculateMove(defaultCurrent!, statetmp, number);
    if (arr) {
      setState(arr);
    }
    return number;
  }, [pageSize, total]);

  return (
    <PageUl style={{ display: 'flex' }}>
      <li>
        <Button
          appearance="primaryOutline"
          disabled={current === 1}
          onClick={() => {
            if (state.length === 0) return;
            // 点击上一页
            if (state[0] > 1) {
              // 页码从1开始
              let statetmp = state.map(v => v - 1);
              setState(statetmp);
              setCurrent(current! - 1);
              let arr = calculateMove(current! - 1, statetmp, totalPage);
              arr && setState(arr);
            } else if (current !== state[0]) {
              setCurrent(current! - 1);
              let arr = calculateMove(current! - 1, state, totalPage);
              arr && setState(arr);
            }
          }}
        >
          <Icon icon="arrowleft" color={color.primary} />
        </Button>
      </li>
      {state.map((v, i) => (
        <li key={i}>
          <Button
            appearance={current === v ? 'primary' : 'primaryOutline'}
            onClick={() => {
              setCurrent(v);
              let arr = calculateMove(v, state, totalPage);
              arr && setState(arr);
            }}
          >
            {v}
          </Button>
        </li>
      ))}
      <li>
        <Button
          appearance="primaryOutline"
          disabled={current === totalPage}
          onClick={() => {
            if (state.length === 0) return;
            // 点击下一页
            if (state[barMaxSize! - 1] < totalPage) {
              let statetmp = state.map(v => v + 1);
              setState(statetmp);
              setCurrent(current! + 1);
              let arr = calculateMove(current! + 1, statetmp, totalPage);
              arr && setState(arr);
            } else if (current !== totalPage) {
              setCurrent(current! + 1);
              let arr = calculateMove(current! + 1, state, totalPage);
              arr && setState(arr);
            }
          }}
        >
          <Icon icon="arrowright" color={color.primary} />
        </Button>
      </li>
    </PageUl>
  );
}

//--------------table表格--------------------

export interface SourceDataType {
  key: string;
  [key: string]: any;
}

export interface ColumnType {
  title: ReactNode;
  dataIndex: string;
  sorter?: {
    compare: (a: SourceDataType, b: SourceDataType) => number;
  };
  render?: (v: any, value: SourceDataType, rowData: ColumnType) => ReactNode;
}

const MapData = (data: SourceDataType[], columnData: ColumnType[]) => {
  return data.map(v => {
    return (
      <tr key={v.key}>
        {columnData.map((value, index) => {
          return (
            <td key={index}>
              <span>
                {value.render ? value.render(v[value.dataIndex], v, value) : v[value.dataIndex]}
              </span>
            </td>
          );
        })}
      </tr>
    );
  });
};

export type TableProps = {
  /** 表内数据部分 */
  data: SourceDataType[];
  /** 表头部分 */
  columns: ColumnType[];
  /** 是否开启排序 */
  sorted?: boolean;
  /** 是否开启分页 */
  pagination?: boolean;
  /** 每页显示条数，开启分页时有效 */
  pageSize?: number;
};

Table.defaultProps = {
  sorted: false,
  pagination: false,
  pageSize: 10,
};

export function Table(props: PropsWithChildren<TableProps>) {
  const { data, columns, sorted, pageSize, pagination } = props;
  const [columnData, setColumnData] = useState<ColumnType[]>([]);
  const [sourceData, setSourceData] = useState<SourceDataType[]>([]);
  const [paginationData, setPaginationData] = useState<SourceDataType[][]>([]);
  const [current, setCurrent] = useState(0);

  // 排序
  const [sortedData, setSortedData] = useState<SourceDataType[]>([]);
  const [filterState, setFilterState] = useState<number[]>([]); //记录第几列开启

  const originPagination = useMemo(() => {
    return (data: SourceDataType[]) => {
      let tmp: SourceDataType[][] = [];
      let len = data.length;
      let pagenumber = Math.ceil(len / pageSize!);
      for (let i = 0; i < pagenumber; i++) {
        tmp[i] = data.slice(0 + i * pageSize!, pageSize! + i * pageSize!);
      }
      setPaginationData(tmp);
    };
  }, [pageSize]);

  const totalColumn = useMemo(() => {
    setColumnData(columns);
    setFilterState(new Array(columns.length).fill(0)); //初始化排序数据
    return columns.length;
  }, [columns]);

  const totalLen = useMemo(() => {
    // 内容部分总长
    setSourceData(data);
    if (pagination) {
      originPagination(data);
    }
    return data.length;
  }, [data, originPagination, pagination]);

  const renderData = useMemo(() => {
    // 内容部分渲染
    let render;
    if (pagination && paginationData.length !== 0) {
      render = MapData(paginationData[current], columnData);
    } else {
      //否则直接渲染
      if (sortedData.length === 0) {
        render = MapData(sourceData, columnData);
      } else {
        //如果排序有数据，就按排序渲染
        render = MapData(sortedData, columnData);
      }
    }
    return render;
  }, [columnData, current, pagination, paginationData, sourceData]);

  const handleSort = (v: ColumnType, i: number) => {
    if (filterState[i]) {
      //如果已经开启了排序
      //查看是不是1，如果为1，进行逆序排序，否则清空
      if (filterState[i] === 1) {
        let res = sourceData.slice().sort((a, b) => -v.sorter!.compare(a, b)); //数据传给compare
        let newfilter = new Array(totalColumn).fill(0);
        newfilter[i] = 2;
        setSortedData(res);
        setFilterState(newfilter);
      } else {
        setSortedData([]); //清空排序数据
        if (pagination) {
          originPagination(data);
        }
        filterState[i] = 0;
        setFilterState([...filterState]);
      }
    } else {
      //没有开启就开启排序
      let res = sourceData.slice().sort(v.sorter!.compare); //数据传给compare
      let newfilter = new Array(totalColumn).fill(0);
      newfilter[i] = 1;
      setSortedData(res);
      setFilterState(newfilter);
    }
  };

  return (
    <div>
      <TableTable>
        <thead>
          <tr>
            {columnData.map((v, i) => (
              <th key={i}>
                <span>{v.title}</span>
                {/* 需要排序 */}
                {v.sorter && sorted && v.sorter.compare && (
                  <TableHeadSpan onClick={() => handleSort(v, i)}>
                    <Icon
                      icon="arrowup"
                      block
                      color={filterState[i] === 1 ? color.primary : color.dark}
                    />
                    <Icon
                      icon="arrowdown"
                      block
                      color={filterState[i] === 2 ? color.primary : color.dark}
                    />
                  </TableHeadSpan>
                )}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>{renderData}</tbody>
      </TableTable>
      {pagination && (
        <Pagination
          style={{ justifyContent: 'flex-end' }}
          total={totalLen}
          pageSize={pageSize}
          callback={v => setCurrent(v - 1)}
          defaultCurrent={1}
        ></Pagination>
      )}
    </div>
  );
}
